﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace CodeMonkey.EditableObject.Core
{
    // from http://www.cnblogs.com/dingli/archive/2012/06/14/2548687.html
    [Obsolete("备用,,,亮点在于使用properties全局缓存")]
    public class DynamicBindingProxy<T> : DynamicObject, INotifyPropertyChanged
    {
        private static readonly Dictionary<string, Dictionary<string, PropertyInfo>> properties =
       new Dictionary<string, Dictionary<string, PropertyInfo>>();//存放T 的属性
        private readonly T _instance;
        private readonly string _typeName;

        public DynamicBindingProxy(T instance)
        {
            _instance = instance;
            var type = typeof(T);
            _typeName = type.FullName;
            if (!properties.ContainsKey(_typeName))
                SetProperties(type, _typeName);
        }

        private static void SetProperties(Type type, string typeName)
        {
            var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            var dict = props.ToDictionary(prop => prop.Name);
            properties.Add(typeName, dict);
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (properties[_typeName].ContainsKey(binder.Name))
            {
                result = properties[_typeName][binder.Name].GetValue(_instance, null);
                return true;
            }
            result = null;
            return false;
        }
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (properties[_typeName].ContainsKey(binder.Name))
            {
                properties[_typeName][binder.Name].SetValue(_instance, value, null);
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(binder.Name));
                }
                return true;
            }
            return false;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
